<?php

namespace App\Http\Controllers;

use DB;
use Illuminate\Http\Request;
use Validator;

class InformController extends Controller
{
    function show(Request $request, $id){
        $input = $request->all();
        //参数检验
        $validator = Validator::make($input,
            [
                'user_id'     => 'integer|min:1'
            ]
        );
        if($validator->fails()){
            return $this::jsonResponse(true,$validator->messages(),"paramError");
        }

        //通知
        $informResult = DB::select("SELECT im_inform.id,im_inform.title,im_inform.content,im_inform.sender_id,
            im_inform.send_count,im_inform.replied_count,im_inform.send_time,im_inform.is_closed,im_inform.close_time,im_inform.is_urgent,im_inform.is_notcare,
            im_set.name AS set_name,im_set.icon AS set_icon,
            im_user.name AS sender_name,im_user.icon AS sender_icon
            FROM im_inform
            INNER JOIN im_set ON im_set.id = im_inform.set_id
            LEFT JOIN im_user ON im_user.id = im_inform.sender_id
            WHERE im_inform.id = $id AND im_inform.is_deleted = false
            ");

        if(empty($informResult)){
            return $this::jsonResponse(true,[],"InformNull");
        }

        $informResult = $informResult[0];

        //通知方式
        $informResult->inform_method = DB::table("im_inform_method")
            ->select("im_inform_method.id","im_inform_method.could_send","im_inform_method.could_send_time",
                "im_inform_method.is_sent","im_inform_method.send_time","im_inform_method.method_id",
                "im_method.name AS method_name","im_method.icon AS method_icon"
                )
            ->join("im_method","im_method.id","=","im_inform_method.method_id")
            ->where("im_inform_method.inform_id",$id)
            ->orderBy("im_inform_method.is_sent","DESC")
            ->orderBy("im_inform_method.could_send_time","ASC")
            ->get();

        //通知人
        $informResult->inform_user = DB::table("im_inform_user")
            ->select("im_inform_user.id","im_inform_user.user_id",
                "im_inform_user.reply_time","im_inform_user.attached_msg",
                "im_inform_user.reply_opt_id","im_inform_user.reply_method_id",
                "im_user.name AS user_name","im_user.icon AS user_icon",
                "im_reply_opt.content AS reply_opt_content",
                "im_method.name AS reply_method_name","im_method.icon AS reply_method_icon"
                )
            ->join("im_user","im_user.id","=","im_inform_user.user_id")
            ->leftJoin("im_reply_opt","im_reply_opt.id","=","im_inform_user.reply_opt_id")
            ->leftJoin("im_method","im_method.id","=","im_inform_user.reply_method_id")
            ->where("im_inform_user.inform_id",$id)
            ->orderBy("im_inform_user.reply_opt_id","ASC")
            ->get();

        //通知回复项
        $informResult->inform_reply_opt = DB::table("im_reply_opt")
            ->select("id","content","is_expected","url_page","replied_count")
            ->where("inform_id",$id)
            ->get();
        
        //回复内容
        if(isset($input["user_id"])){
            $userId = $input["user_id"];
            $informResult->is_own = $userId == $informResult->sender_id?1:0;
            $messageResult = DB::table("im_inform_user")
                ->select("im_inform_user.id","special","token","reply_time","attached_msg",
                    "reply_opt_id","reply_method_id",
                    "im_reply_opt.content AS reply_opt_content",
                    "im_method.name AS reply_method_name","im_method.icon AS reply_method_icon"
                    )
                ->leftJoin("im_reply_opt","im_reply_opt.id","=","im_inform_user.reply_opt_id")
                ->leftJoin("im_method","im_method.id","=","im_inform_user.reply_method_id")
                ->where("im_inform_user.inform_id",$id)
                ->where("im_inform_user.user_id",$userId)
                ->first();
            $informResult->could_reply = (empty($messageResult) || $informResult->is_closed == 1)?0:1;
            $informResult->message     = $messageResult;

            //改为看过状态
            DB::table("im_set_user")
                ->where("inform_id",$id)
                ->where("user_id",$userId)
                ->update(["is_viewed"=>true]);
        }

        return $this::jsonResponse(false,$informResult);
    }

    public function store(Request $request)
    {
        $input = $request->all();

        //参数检验
        $validator = Validator::make($input,
            [
                'title'     => 'required|string|min:1',
                'app_id'    => 'required|integer|min:1',
                'sender_id' => 'required|integer|min:1',
                'is_urgent' => 'boolean',
                'is_notcare' => 'boolean',
                'is_reply_inform' => 'boolean',
                'set_id'    => 'integer|min:1',
                'content'   => 'string|min:1',
                'could_send_time'       => 'date|after:'.date("Y-m-d H:i:s"),
                'close_trigger_type'    => 'numeric',
                'close_trigger_value'   => 'numeric',
                'final_close_time'      => 'date|after:'.date("Y-m-d H:i:s"),
                'users'     =>'array',
                'methods'   =>'array',
                'reply_opts'=>'array'
            ]
        );
        if($validator->fails()){
            return $this::jsonResponse(true,$validator->messages(),"paramError");
        }
        //继续检查
        $appId    = $input["app_id"];
        $senderId = $input["sender_id"];

        //短信语音条数限制
        $messageCount = DB::table("im_inform_user_method")
            ->join("im_inform","im_inform.id","=","im_inform_user_method.inform_id")
            ->where("im_inform.sender_id",$senderId)
            ->whereIn("im_inform_user_method.method_id",[3,4])
            ->where("im_inform_user_method.send_time","LIKE",date("Y-m")."%")
            ->count();
        $userResult  = DB::table("im_user")->select("id","name","mlimit_count")->where("id",$senderId)->first();
        $mLimitCount = $userResult->mlimit_count;
        if($messageCount > $mLimitCount){
            return $this::jsonResponse(true,["count"=>$messageCount,"limit"=>$mLimitCount],"InformLimitFull");
        }

        //通知集id
        if(!isset($input["set_id"])){
            $setResult = DB::select("SELECT id FROM im_set WHERE app_id=$appId ORDER BY id ASC LIMIT 1");
            if(empty($setResult)) return $this::jsonResponse(true,[],"InformSetNull");
            $input["set_id"] = $setResult[0]->id;
        }

        //创建通知
        $informData = [
            "title"         =>(empty($input["is_urgent"])?"":"[紧急]").$input["title"],
            "app_id"        =>$appId,
            "set_id"        =>$input["set_id"],

            "sender_id"     =>$senderId,
            "content"       =>!empty($input["content"])?$input["content"]:"",
            "is_urgent"        =>!empty($input["is_urgent"])?$input["is_urgent"]:0,
            "is_notcare"       =>!empty($input["is_notcare"])?$input["is_notcare"]:0,
            "could_send_time"        =>!empty($input["could_send_time"])?$input["could_send_time"]:"",
            "close_trigger_type"     =>!empty($input["close_trigger_type"])?$input["close_trigger_type"]:"",
            "close_trigger_value"    =>!empty($input["close_trigger_value"])?$input["close_trigger_value"]:"",
            "final_close_time"       =>!empty($input["final_close_time"])?$input["final_close_time"]:"",
            "is_reply_inform"        =>!empty($input["is_reply_inform"])?$input["is_reply_inform"]:0,
        ];

        DB::beginTransaction();
        $informId = DB::table("im_inform")->insertGetId($informData);
        
        //被通知人
        if(!empty($input["users"])){
            $userData = [];
            foreach ($input["users"] as $key => $value) {
                if(isset($value["user_id"]) && is_numeric($value["user_id"])){
                    $userData[] = [
                        "inform_id" =>$informId,                      
                        "user_id"   =>$value["user_id"],
                        "token"     =>str_random(5),
                        "special"   =>isset($value["special"])?$value["special"]:"",
                    ];
                }else{
                    DB::rollback();
                    return $this::jsonResponse(true,[],"InformUserIdError");
                }
            }
            if(empty($userData)){
                DB::rollback();
                return $this::jsonResponse(true,[],"InformNoUser");
            }
            DB::table('im_inform_user')->insert($userData);
        }

        //通知方式
        $level = 2;
        //0:无任何通知方式，只在应用内显示
        //1:只以客户端/微信/邮件等非紧急方式发送
        //2:以客户端/微信/邮件等非紧急方式发送，30分后以短信/语音等紧急方式发送
        //3:以客户端/微信/邮件等非紧急方式和短信/语音等紧急方式发送

        if(!empty($input["is_notcare"])) $level = 1;
        if(!empty($input["is_urgent"]))  $level = 3;
        if(isset($input["level"]))       $level = $input["level"];

        if($level > 0){
            $methodData = [
                "1" => ["inform_id"=>$informId,"method_id"=>1,"tpl_id"=>"","trigger_type"=>1,"trigger_value"=>0],
                "2" => ["inform_id"=>$informId,"method_id"=>2,"tpl_id"=>"ptimeinform","trigger_type"=>1,"trigger_value"=>0],
                "5" => ["inform_id"=>$informId,"method_id"=>5,"tpl_id"=>env("WECHAT_TEMP_ID"),"trigger_type"=>1,"trigger_value"=>0],
            ];

            if($level>1){
                $UrgentTriggerValue = ($level == 3)?0:1800;
                $methodData["3"] = ["inform_id"=>$informId,"method_id"=>3,"tpl_id"=>"743453","trigger_type"=>1,"trigger_value"=>$UrgentTriggerValue];
                $methodData["4"] = ["inform_id"=>$informId,"method_id"=>4,"tpl_id"=>"","trigger_type"=>1,"trigger_value"=>$UrgentTriggerValue];
            }
        }

        if(!empty($input["methods"])){
            $methodData = [];
            foreach ($input["methods"] as $key => $value) {
                if(isset($value["method_id"]) && is_numeric($value["method_id"])){
                    $methodData[$value["method_id"]] = [
                        "inform_id"     =>$informId,
                        "method_id"     =>$value["method_id"],
                        "tpl_id"        =>!empty($value["tpl_id"])?$value["tpl_id"]:"",
                        "trigger_type"  =>!empty($value["trigger_type"])?$value["trigger_type"]:1,
                        "trigger_value" =>!empty($value["trigger_value"])?$value["trigger_value"]:0,
                    ];
                }else{
                    DB::rollback();
                    return $this::jsonResponse(true,[],"InformMethodIdError");
                }
            }
        }
        if(!empty($methodData))
            DB::table('im_inform_method')->insert($methodData);
        
        //回复选项
        if(!empty($input["reply_opts"])){
            $replyOptData    = [];
            $existIsExpected = false;
            foreach($input["reply_opts"] as $key => $value) {
                if(isset($value["content"]) && !empty($value["content"])){
                    $replyOptData[] = [
                        "inform_id"     =>$informId,
                        "content"       =>$value["content"],
                        "keyword"       =>!empty($value["keyword"])?$value["keyword"]:"",
                        "is_expected"   =>!empty($value["is_expected"])?$value["is_expected"]:false,
                        "url_hook"      =>!empty($value["url_hook"])?$value["url_hook"]:"",
                        "url_page"      =>!empty($value["url_page"])?$value["url_page"]:""
                    ];
                    if(!empty($value["is_expected"]))
                        $existIsExpected = true;
                }else{
                    DB::rollback();
                    return $this::jsonResponse(true,[],"InformReplyContentError");
                }
            }
            if(!$existIsExpected && !empty($replyOptData))
                $replyOptData[0]["is_expected"] = true;
            DB::table('im_reply_opt')->insert($replyOptData);
        }

        DB::commit();

        return $this::jsonResponse(false,$informId);
    }


    public function update(Request $request,$id)
    {
        
    }

    public function close($id)
    {   
        $informCloseData = [
            "is_closed"  =>true,
            "close_time" =>date("Y-m-d H:i:s")
        ];
        $informCloseResult = DB::table("im_inform")->where("id",$id)->update($informCloseData);
        DB::table("im_inform_user_method")->where("inform_id",$id)->whereNull("send_code")->update(["send_code"=>0]);
        return $this::jsonResponse(false,$informCloseResult);
    }

    public function send(Request $request)
    {
        $input = $request->all();
        DB::beginTransaction();
        $informResult = $this->api->with($input)->post("inform");
        if($informResult["error"]){
            DB::rollback();
            return $informResult;
        }

        $informId = $informResult["result"];
        $informSendResult = $this->api->put("inform/$informId/send");
        if($informSendResult["error"]){
            DB::rollback();
            return $informSendResult;
        }

        DB::commit();
        return $this::jsonResponse(false,$informId);

    }

    public function destroy($id){
        
    }
}
